/* * Sun Public License Notice * * The contents of this file are subject to the Sun Public License * Version 1.0 (the "License"). You may not use this file except in * compliance with the License. A copy of the License is available at * http://www.sun.com/ * * The Original Code is Forte for Java, Community Edition. The Initial * Developer of the Original Code is Sun Microsystems, Inc. Portions * Copyright 1997-2000 Sun Microsystems, Inc. All Rights Reserved. */ package org.openide.windows; import java.awt.Image; import java.awt.Dimension; import java.awt.Rectangle; import java.awt.Insets; import java.awt.event.KeyEvent; import java.util.*; import java.beans.*; import java.io.ObjectInput; import java.io.ObjectOutput; import java.io.ObjectOutputStream; import java.io.ObjectInputStream; import java.io.Externalizable; import java.io.Serializable; import java.io.IOException; import java.io.ObjectStreamException; import java.lang.reflect.Method; import java.lang.ref.Reference; import java.lang.ref.WeakReference; import javax.swing.JComponent; import javax.swing.undo.UndoableEdit; import javax.swing.FocusManager; import javax.swing.SwingUtilities; import javax.swing.KeyStroke; import org.openide.*; import org.openide.awt.UndoRedo; import org.openide.loaders.*; import org.openide.actions.*; import org.openide.util.actions.SystemAction; import org.openide.nodes.*; import org.openide.util.NbBundle; import org.openide.util.WeakListener; import org.openide.util.HelpCtx; /** Embeddable visual component to be displayed in the IDE. * This is the basic unit of display in the IDE--windows should not be * created directly, but rather use this class. * A top component may correspond to a single window, but may also * be a tab (e.g.) in a window. It may be docked or undocked, * have selected nodes, supply actions, etc. * * @author Jaroslav Tulach, Petr Hamernik, Jan Jancura */ public class TopComponent extends JComponent implements Externalizable { /** generated Serialized Version UID */ static final long serialVersionUID = -3022538025284122942L; /** instance of registry */ private static Registry registry; /** Behavior in which a top component closed (by the user) in one workspace * will be removed from <em>every</em> workspace. * Also, {@link #close} is called. * This is appropriate for top components such as Editor panes which * the user expects to really close (and prompt to save) when closed * in any workspace. */ public static final int CLOSE_EACH = 0; /** Behavior in which a top component closed (by the user) in one workspace * may be left in other workspaces. * Only when the last remaining manifestation in any workspace is closed * will the object be deleted using {@link #close}. * Appropriate for components containing no user data, for which closing * the component is only likely to result from the user's wanting to remove * it from active view (on the current workspace). */ public static final int CLOSE_LAST = 1; /** a set of actions of this component */ private static SystemAction[] systemActions; /** Listener to the data object's node or null */ private NodeName nodeName; /** manager for the component */ private WindowManager.Component manager; /** constant for desired close operation */ private int closeOperation = CLOSE_LAST; /** identification of serialization version * Used in CloneableTopComponent readObject method. */ short serialVersion = 1; /** Create a top component. */ public TopComponent () { FocusMan.install(); enableEvents (java.awt.AWTEvent.KEY_EVENT_MASK); // there is no reason why a top component should have a focus // => let's disable it setRequestFocusEnabled (false); // request creating of our manager - it's here to avoid // problems with recreating the connections between top components // and their managers during deserialization getManager(); } /** Create a top component associated with a data object. * Currently the data object is used to set the component's name * (which will be updated according to the object's node delegate) by * installing NodeName inner class and attaching it to the node delegate. * * @param obj the data object */ public TopComponent (DataObject obj) { this (); Node n = obj.getNodeDelegate (); nodeName = new NodeName (this); nodeName.attach (n); } /** Getter for class that allows obtaining of information about components. * It allows to find out which component is selected, which nodes are * currently or has been activated and list of all components. * * @return the registry of components */ public static final Registry getRegistry () { if (registry == null) { registry = TopManager.getDefault().getWindowManager(). componentRegistry(); } return registry; } /** Get the set of activated nodes in this component. * @return the activated nodes for this component */ public final Node[] getActivatedNodes () { return getManager ().getActivatedNodes (); } /** Set the set of activated nodes in this component. * @param nodes activated nodes for this component */ public final void setActivatedNodes (Node[] nodes) { getManager ().setActivatedNodes (nodes); firePropertyChange ("activatedNodes", null, null); // NOI18N } /** Get the undo/redo support for this component. * The default implementation returns a dummy support that cannot * undo anything. * * @return undoable edit for this component */ public UndoRedo getUndoRedo () { return UndoRedo.NONE; } /** Show the component on current workspace. * Note that this method only makes it visible, but does not * give it focus. Implemented via call to open(null). * @see #requestFocus */ public void open () { open(null); } /** Show the component on given workspace. If given workspace is * not active, component will be shown only after given workspace * will become visible. * Note that this method only makes it visible, but does not * give it focus. * @param workspace Workspace on which component should be opened. * Parameter can be null -> means current workspace. * @see #requestFocus */ public void open (Workspace workspace) { getManager().open(workspace); } /** Finds out if this top component is opened at least on one workspace. * @return true if given top component is opened on at least * one workspace, false otherwise */ public final boolean isOpened () { return getManager().whereOpened().size() > 0; } /** Finds out whether this top component is opened or not on specified * workspace. * @return true if given top component is opened on given workspace, * false otherwise */ public final boolean isOpened (Workspace workspace) { return getManager().whereOpened().contains(workspace); } /** Closes the top component on current workspace. * First asks canClose() method to see if it is * possible to close now. If canClose() returns false, component will not * be closed. * Semantics of this method depends on top component's closeOperation * state. If closeOperation is set to CLOSE_LAST (default), top component * will be closed only on current workspace. If it is set to * CLOSE_EACH, if will be closed on all workspaces at once. * * @return true if top component was succesfully closed, false if * top component for some reason refused to close. */ public final boolean close () { return close( TopManager.getDefault().getWindowManager().getCurrentWorkspace() ); } /** Closes the top component on given workspace, if closeOperation * is set to CLOSE_LAST. If it is set to CLOSE_EACH, given parameter * will be ignored and component will be closed on all workspaces * at once. * * @param workspace Workspace on which component should be closed. * @return true if top component was succesfully closed, false if * top component for some reason refused to close. */ public final boolean close (Workspace workspace) { Set whereOpened = getManager().whereOpened(); // don't close multiple times if ((closeOperation != CLOSE_EACH) && !whereOpened.contains(workspace)) return true; boolean result = false; switch (closeOperation) { case CLOSE_LAST: result = canClose(workspace, whereOpened.size() == 1); break; case CLOSE_EACH: result = canClose(null, true); break; } if (result) getManager().close(workspace); return result; } /** This method is called when top component is about to close. * Allows subclasses to decide if top component is ready for closing * or not.<br> * Default implementation always return true. * * @param workspace the workspace on which we are about to close or * null which means that component will be closed * on all workspaces where it is opened (CLOSE_EACH mode) * @param last true if this is last workspace where top component is * opened, false otherwise. If close operation is set to * CLOSE_EACH, then this param is always true * @return true if top component is ready to close, false otherwise. */ public boolean canClose (Workspace workspace, boolean last) { return true; } /** Get a list of modes which are allowed for this component. * The component can be displayed only in the indicated modes. * The current mode should <em>not</em> be included. * <p>Subclasses are encouraged to override this method to allow * only modes appropriate to the application's needs. * The default implementation treats all modes as allowed except the current * mode. * * @param w workspace to check allowed modes on * @return an immutable list of allowed modes */ // PENDING - we will priobably remove it /* public java.util.List getAllowedModes (Workspace w) { java.util.List availModes = w.getModes(); availModes.remove(w.findMode (this)); return availModes; }*/ /** Get the system actions which will appear in * the popup menu of this component. * <p>Subclasses are encouraged to override this method to specify * their own sets of actions. * <p>Remember to call the super method when overriding and add your actions * to the superclass' ones (in some order),? * because the default implementation provides support for standard * component actions like save, close, and clone. * @return system actions for this component */ public SystemAction[] getSystemActions () { // lazy inicialization if (systemActions == null) systemActions = new SystemAction[] { SystemAction.get(SaveAction.class), SystemAction.get(CloneViewAction.class), null, SystemAction.get(CloseViewAction.class) }; return systemActions; } /** Set the close mode for the component. * Note that if the {@link #close} is called (rather than a user-initiated close action), the component (and maybe its * window) is always removed from all workspaces.<P> * * @param mode one of {@link #CLOSE_EACH} or {@link #CLOSE_LAST} * @throws IllegalArgumentException if an unrecognized close mode was supplied */ public final void setCloseOperation (final int closeOperation) { if ((closeOperation != CLOSE_EACH) && (closeOperation != CLOSE_LAST)) throw new IllegalArgumentException( NbBundle.getBundle(TopComponent.class).getString("EXC_UnknownOperation") ); if (this.closeOperation == closeOperation) return; this.closeOperation = closeOperation; firePropertyChange ("closeOperation", null, null); // NOI18N } /** Get the current close mode for this component. * @return one of {@link #CLOSE_EACH} or {@link #CLOSE_LAST} */ public final int getCloseOperation () { return closeOperation; } /** Called when this component is activated. * This happens when the parent window of this component gets focus * (and this component is the preferred one in it), <em>or</em> when * this component is selected in its window (and its window was already focussed). * Override this method to perform some special action on component activation: * typically, set performers for relevant actions. * Remember to call the super method. * The default implementation does nothing. */ protected void componentActivated () { } /** Called when this component is deactivated. * This happens when the parent window of this component loses focus * (and this component is the preferred one in the parent), * <em>or</em> when this component loses preference in the parent window * (and the parent window is focussed). * Override this method to perform some special action on component deactivation: * typically, unset performers for relevant actions. * Remember to call the super method. * The default implementation does nothing. */ protected void componentDeactivated () { } // [PENDING] would a call to setMode in the constructor suffice? /** Get the default mode for this component. * This is the mode in which it will be opened for the first time. * The default implementation returns {@link #SINGLE}. * * @return the default mode */ // Can we get rid of this? // protected Mode getDefaultMode () { // return SINGLE; // } /** Request focus for the window holding this top component. * Also makes the component preferred in that window. * The component will <em>not</em> be automatically {@link #open opened} first * if it is not already. */ public void requestFocus () { //System.out.println("RF on tc " + getName() + " called."); // NOI18N getManager().requestFocus(); super.requestFocus(); } /** Set the name of this top component. * The default implementation just notifies the window manager. * @param displayName the new display name */ public void setName (final String name) { if ((name != null) && (name.equals(getName()))) return; // This should also be firing a property change event: super.setName(name); getManager().nameChanged(); } /** Set the icon of this top component. * The icon will be used for * the component's representation on the screen, e.g. in a multiwindow's tab. * The default implementation just notifies the window manager. * @param icon New components' icon. */ public void setIcon (final Image icon) { getManager().setIcon(icon); firePropertyChange ("icon", null, null); // NOI18N } /** @return The icon of the top component */ public Image getIcon () { return getManager().getIcon(); } /** Set the (preferred) size of the top component. * Use this method to dynamically change the size of a top component * (the container should change its size to match). * It is possible the new size will not be honored if it is impossible to * fit it. * @param size new size of this top component */ // use Workspace.findMode (TopComponent).setBounds (..) // public void setRequestedSize (final Dimension size) { // getManager().setRequestedSize(size); // } /** Get the help context for this component. * Subclasses should generally override this to return specific help. * @return the help context */ public org.openide.util.HelpCtx getHelpCtx () { return new HelpCtx (TopComponent.class); } /** Getter for manager for this component. This manager allows to * control where is the component shown can be used to destroy and show the * component, etc. */ final WindowManager.Component getManager () { if (manager == null) { synchronized (this) { if (manager == null) { manager = TopManager.getDefault ().getWindowManager ().createTopComponentManager ( this ); } } } return manager; } /** Serialize this top component. * Subclasses wishing to store state must call the super method, then write to the stream. * @param out the stream to serialize to */ public void writeExternal (ObjectOutput out) throws IOException { out.writeObject(new Short (serialVersion)); out.writeInt (closeOperation); out.writeObject (getName()); out.writeObject (getToolTipText()); Node.Handle h = nodeName == null ? null : nodeName.node.getHandle (); out.writeObject(h); } /** Deserialize this top component. * Subclasses wishing to store state must call the super method, then read from the stream. * @param in the stream to deserialize from */ public void readExternal (ObjectInput in) throws IOException, ClassNotFoundException { Object firstObject = in.readObject (); if (firstObject instanceof Integer) { // backward compatibility read serialVersion = 0; closeOperation = ((Integer)firstObject).intValue(); DataObject obj = (DataObject)in.readObject(); super.setName((String)in.readObject()); setToolTipText((String)in.readObject()); // initialize the connection to a data object if (obj != null) { nodeName = new NodeName (this); nodeName.attach (obj.getNodeDelegate ()); } } else { // new serialization serialVersion = ((Short)firstObject).shortValue (); closeOperation = in.readInt (); super.setName ((String)in.readObject ()); setToolTipText ((String)in.readObject ()); Node.Handle h = (Node.Handle)in.readObject (); if (h != null) { Node n = h.getNode (); nodeName = new NodeName (this); nodeName.attach (n); } } } /** Delegates instance of replacer class to be serialized instead * of top component itself. Replacer class calls writeExternal and * constructor, readExternal and readResolve methods properly, so 8 any top component can behave like any other externalizable object. * Subclasses can override this method to perform their * serialization differentrly */ protected Object writeReplace () throws ObjectStreamException { return new Replacer(this); } /** Each top component that wishes to be cloned should implement * this interface, so CloneAction can check it and call the cloneComponent * method. */ public static interface Cloneable { /** Creates a clone of this component * @return cloned component. */ public TopComponent cloneComponent (); } /** This class provides the connection between the node name and * a name of the component. */ public static class NodeName extends NodeAdapter { /** weak reference to the top component */ private transient Reference top; /** node we are attached to or null */ private transient Node node; /** Constructs new name adapter that * can be attached to any node and will listen on changes * of its display name and modify the name of the component. * * @param top top compoonent to modify its name */ public NodeName (TopComponent top) { this.top = new WeakReference (top); } /** Attaches itself to a given node. */ final void attach (Node n) { TopComponent top = (TopComponent)this.top.get (); if (top != null) { synchronized (top) { // ok no change if (n == node) return; // change the node we are attached to if (node != null) { node.removeNodeListener (this); } node = n; if (n != null) { n.addNodeListener (this); top.setActivatedNodes (new Node[] { n }); top.setName (n.getDisplayName ()); } } } } /** Listens to Node.PROP_DISPLAY_NAME. */ public void propertyChange(PropertyChangeEvent ev) { TopComponent top = (TopComponent)this.top.get (); if (top == null) { // stop listening if top component no longer exists if (ev.getSource () instanceof Node) { Node n = (Node)ev.getSource (); n.removeNodeListener (this); } return; } // ensure we are attached attach (node); if (ev.getPropertyName ().equals (Node.PROP_DISPLAY_NAME)) { top.setName (node.getDisplayName()); } } } // end of NodeName /** Our focus manager to catch keys. */ static class FocusMan extends FocusManager { /** manager to deletage operations to */ private FocusManager delegate; /** @param d delegate focus manager */ private FocusMan (FocusManager d) { delegate = d; } /** Checks whether the calling thread uses this focus manager. * If no, installs new one. */ public static void install () { FocusManager fm = getCurrentManager (); if (fm == null || fm.getClass () != FocusMan.class) { setCurrentManager (new FocusMan (fm)); } } /** Processes the key */ public void processKeyEvent( java.awt.Component focusedComponent, final java.awt.event.KeyEvent anEvent ) { if (ShortcutManager.isTransmodalAction (KeyStroke.getKeyStrokeForEvent (anEvent))) { //System.err.println ("Got a transmodal action..."); } else { // Bug #500 fixed here. and #2482 too. java.awt.Component c = focusedComponent; java.awt.Component mw = TopManager.getDefault ().getWindowManager ().getMainWindow (); java.awt.Window w = SwingUtilities.windowForComponent (c); if (w instanceof java.awt.Dialog) { java.awt.Dialog d = (java.awt.Dialog)w; if (d.isModal ()) { return; } } } /* while (true) { System.err.println ("Considering: " + c); if ((c instanceof TopComponent) || (c == mw)) { //System.err.println ("Fine, MW or TC."); break; } else if (c instanceof java.awt.Dialog) { //System.err.println ("Some window, maybe dialog; skip."); return; } else if (c instanceof java.awt.Window) { // other top window, proceed bugfix of #2482 break; } else { c = c.getParent (); } } } */ // delegates to the original focus manager delegate.processKeyEvent (focusedComponent, anEvent); //System.err.println ("Was consumed by delegate: " + anEvent.isConsumed ()); if (!anEvent.isConsumed ()) { process (anEvent, focusedComponent); } } /** Delegates to old manager */ public void focusNextComponent(java.awt.Component aComponent) { delegate.focusNextComponent (aComponent); } /** Delegates to old manager */ public void focusPreviousComponent(java.awt.Component aComponent) { delegate.focusPreviousComponent (aComponent); } /** HashSet of posted events. Ensures that no event will be posted * twice. (KeyEvent, KeyEvent) * @associates KeyEvent */ private static HashSet posted = new HashSet (); /** Processes the event by posting it to shortcut processor. * @param ev the event to process */ static void process (final KeyEvent ev, final java.awt.Component comp) { // test if ev is not posted //System.err.println ("Maybe processing.."); if (ev.getID () != KeyEvent.KEY_PRESSED || posted.contains (ev)) return; // register that this event has been posted posted.add (ev); //System.err.println ("Posting..."); // if the event is not consumed, then plans code // that will be run after the event is processed by component // an will try to find the right shortcut SwingUtilities.invokeLater (new Runnable () { public void run () { //System.err.println ("Running later; was consumed: " + ev.isConsumed ()); if (!ev.isConsumed ()) { // process only if the event is not consumed KeyStroke key = KeyStroke.getKeyStrokeForEvent (ev); java.awt.Component source = comp; // first guess // For menu items, the first guess does not work well--really we want // to examine the currently open menu. Note special treatment of submenus // which are open, but no items selected--ignore, and use the JMenu instead. javax.swing.MenuElement[] menuitems = javax.swing.MenuSelectionManager.defaultManager ().getSelectedPath (); if (menuitems != null) { for (int idx = menuitems.length - 1; idx >= 0; idx--) { java.awt.Component menuitem = menuitems[idx].getComponent (); if (! (menuitem instanceof javax.swing.JPopupMenu) && (menuitem != null)) { source = menuitem; break; } } } // Provide a reasonably useful action event that identifies what was focused // when the key was pressed, as well as what keystroke ran the action. java.awt.event.ActionEvent aev = new java.awt.event.ActionEvent (source, java.awt.event.ActionEvent.ACTION_PERFORMED, org.openide.util.Utilities.keyToString (key)); if (ShortcutManager.processKeyStroke (key, aev)) { ev.consume (); } } posted.remove (ev); } }); } } /* Focus watcher hack. static { class T implements Runnable { public void run () { TopComponent tc = getRegistry ().getActivated (); java.awt.Component c = SwingUtilities.findFocusOwner (tc); System.out.println("TopComponent: " + tc); System.out.println("Focus owner : " + c); org.openide.util.RequestProcessor.postRequest (this, 2000); } } new T ().run (); } */ /** Registry of all top components. * There is one instance that can be obtained via {@link TopComponent#getRegistry} * and it permits listening to the currently selected element, and to * the activated nodes assigned to it. */ public static interface Registry { /** Name of property for the set of opened components. */ public static final String PROP_OPENED = "opened"; // NOI18N /** Name of property for the selected top component. */ public static final String PROP_ACTIVATED = "activated"; // NOI18N /** Name of property for currently selected nodes. */ public static final String PROP_CURRENT_NODES = "currentNodes"; // NOI18N /** Name of property for lastly activated nodes nodes. */ public static final String PROP_ACTIVATED_NODES = "activatedNodes"; // NOI18N /** Get all opened componets in the system. * * @return immutable set of {@link TopComponent}s */ public Set getOpened (); /** Get the currently selected element. * @return the selected top component, or <CODE>null</CODE> if there is none */ public TopComponent getActivated (); /** Getter for the currently selected nodes. * @return array of nodes or null if no component activated or it returns * null from getActivatedNodes (). */ public Node[] getCurrentNodes (); /** Getter for the lastly activated nodes. Comparing * to previous method it always remembers the selected nodes * of the last component that had ones. * * @return array of nodes (not null) */ public Node[] getActivatedNodes (); /** Add a property change listener. * @param l the listener to add */ public void addPropertyChangeListener (PropertyChangeListener l); /** Remove a property change listener. * @param l the listener to remove */ public void removePropertyChangeListener (PropertyChangeListener l); } /** Instance of this class is serialized instead of TopComponent itself. * Emulates behaviour of serialization of externalizable objects * to keep TopComponent serialization compatible with previous versions. */ private static final class Replacer implements Serializable { /** SUID */ static final long serialVersionUID=-8897067133215740572L; /** Asociation with top component which is to be serialized using * this replacer */ transient TopComponent tc; public Replacer (TopComponent tc) { this.tc = tc; } private void writeObject (ObjectOutputStream oos) throws IOException, ClassNotFoundException { // write the name of the top component first oos.writeObject(tc.getClass().getName()); // and now let top component to serialize itself tc.writeExternal(oos); } private void readObject (ObjectInputStream ois) throws IOException, ClassNotFoundException { // read the name of top component's class, instantiate it // and read its attributes from the stream String name = (String)ois.readObject(); name = org.openide.util.Utilities.translate(name); try { Class tcClass = Class.forName( name, true, TopManager.getDefault().systemClassLoader() ); tc = (TopComponent)tcClass.newInstance(); tc.readExternal(ois); // call readResolve() if present and use resolved value Method resolveMethod = findReadResolveMethod(tcClass); if (resolveMethod != null) { // check exceptions clause Class[] result = resolveMethod.getExceptionTypes(); if ((result.length == 1) && ObjectStreamException.class.equals(result[0])) { // returned value type if (Object.class.equals(resolveMethod.getReturnType())) { // make readResolve accessible (it can have any access modifier) resolveMethod.setAccessible(true); // invoke resolve method and accept its result try { tc = (TopComponent)resolveMethod.invoke(tc, new Class[0]); } finally { resolveMethod.setAccessible(false); } } } } } catch (Exception exc) { // turn all troubles into IOException exc.printStackTrace(); throw new IOException(); } } /** Resolve to original top component instance */ private Object readResolve () throws ObjectStreamException { return tc; } /** Tries to find readResolve method in given class. Finds * both public and non-public occurences of the method and * searches also in superclasses */ private static Method findReadResolveMethod (Class clazz) { Method result = null; // first try public occurences try { result = clazz.getMethod("readResolve", new Class[0]); // NOI18N } catch (NoSuchMethodException exc) { // public readResolve does not exist } // now try non-public occurences; search also in superclasses for (Class i = clazz; i != null; i = i.getSuperclass()) { try { result = i.getDeclaredMethod("readResolve", new Class[0]); // NOI18N // get out of cycle if method found break; } catch (NoSuchMethodException exc) { // readResolve does not exist in current class } } return result; } } // end of Replacer inner class } /* * Log * 48 Gandalf 1.47 2/15/00 David Simonek bug after unmount of * open editor files fixed (hopefully :-) * 47 Gandalf 1.46 1/16/00 David Simonek finding of readResolve * method fixed in replacer object * 46 Gandalf 1.45 1/15/00 Jaroslav Tulach SUID * 45 Gandalf 1.44 1/13/00 David Simonek i18n * 44 Gandalf 1.43 1/12/00 Jesse Glick All setters now fire * JComponent property changes. * 43 Gandalf 1.42 12/21/99 David Simonek #5066 * 42 Gandalf 1.41 12/8/99 Jaroslav Tulach TopComponent enhanced. * 41 Gandalf 1.40 12/7/99 David Simonek serialization changed, * TopComponent now replaceable, class Replacer is serialized instead of * TopComponent itself by default * 40 Gandalf 1.39 11/30/99 David Simonek isOpened () and isOpened * (Workspace) convenience methods added * 39 Gandalf 1.38 11/5/99 Jesse Glick Rearranged context help * for ExplorerPanel vs. TopComponent. * 38 Gandalf 1.37 11/3/99 David Simonek completely rewritten * serialization of windowing system... * 37 Gandalf 1.36 10/22/99 Ian Formanek NO SEMANTIC CHANGE - Sun * Microsystems Copyright in File Comment * 36 Gandalf 1.35 10/7/99 David Simonek request focus modified * 35 Gandalf 1.34 10/6/99 David Simonek more robust * serialization of window system (especially editor TCs) * 34 Gandalf 1.33 9/6/99 Jaroslav Tulach * 33 Gandalf 1.32 8/17/99 Ian Formanek if TopComponent has * CLOSE_EACH the close method does not check if it is opened on the * workspace on which it is being closed * 32 Gandalf 1.31 8/9/99 David Simonek * 31 Gandalf 1.30 7/29/99 David Simonek #2900 bugfix (by Jesse) * 30 Gandalf 1.29 7/28/99 David Simonek canClose() parameters * changed * 29 Gandalf 1.28 7/20/99 Jesse Glick Context help (smarter * guess). * 28 Gandalf 1.27 7/16/99 Jesse Glick Processing keystrokes * with real ActionEvents, handling dialogs better too. * 27 Gandalf 1.26 7/11/99 David Simonek window system change... * 26 Gandalf 1.25 6/8/99 Ian Formanek ---- Package Change To * org.openide ---- * 25 Gandalf 1.24 5/11/99 David Simonek changes to made window * system correctly serializable * 24 Gandalf 1.23 4/27/99 Jesse Glick new HelpCtx () -> * HelpCtx.DEFAULT_HELP. * 23 Gandalf 1.22 4/8/99 David Simonek debigging comments * removed... * 22 Gandalf 1.21 3/31/99 David Simonek ugly ugly ugly * requestFocus bungs fixed * 21 Gandalf 1.20 3/30/99 Jesse Glick [JavaDoc] * 20 Gandalf 1.19 3/30/99 Jesse Glick [JavaDoc] * 19 Gandalf 1.18 3/30/99 Jesse Glick [JavaDoc] * 18 Gandalf 1.17 3/29/99 Jesse Glick [JavaDoc] * 17 Gandalf 1.16 3/29/99 Jesse Glick [JavaDoc] * 16 Gandalf 1.15 3/29/99 Jesse Glick [JavaDoc] * 15 Gandalf 1.14 3/27/99 David Simonek * 14 Gandalf 1.13 3/25/99 David Simonek changes in window * system, initial positions, bugfixes * 13 Gandalf 1.12 3/22/99 David Simonek * 12 Gandalf 1.11 3/19/99 David Simonek * 11 Gandalf 1.10 3/18/99 David Simonek activated nodes bug * fixed * 10 Gandalf 1.9 3/18/99 David Simonek changed window system - * support for modules * 9 Gandalf 1.8 3/14/99 Ian Formanek Temporarily replaced * with older version to make it compilable * 8 Gandalf 1.7 3/14/99 David Simonek * 7 Gandalf 1.6 3/10/99 Jaroslav Tulach UndoRedo * 6 Gandalf 1.5 2/17/99 David Simonek setRequestedSize method * added to the window system getDefaultMode added to the TopComponent * 5 Gandalf 1.4 2/12/99 Ian Formanek Reflected renaming * Desktop -> Workspace * 4 Gandalf 1.3 1/26/99 David Simonek setName optimized a * little bit * 3 Gandalf 1.2 1/8/99 Jan Jancura * 2 Gandalf 1.1 1/6/99 Jaroslav Tulach * 1 Gandalf 1.0 1/5/99 Ian Formanek * $ * Beta Change History: * 0 Tuborg 0.20 --/--/98 Jan Jancura componentActivated / Deactivated added * 0 Tuborg 0.21 --/--/98 Petr Hamernik request focus added */